using CoreManager.API.Common;
using CoreManager.Elasticsearch.Models;
using CoreManager.Elasticsearch.Services;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;

namespace CoreManager.API.System.Controllers;

/// <summary>
/// Elasticsearch搜索引擎控制器
/// </summary>
[ApiController]
[Route("api/[controller]")]
[AllowAnonymous]
public class ElasticsearchController : BaseController
{
    private readonly IElasticsearchService _elasticsearchService;
    private readonly ElasticsearchOptions _esOptions;

    public ElasticsearchController(
        IElasticsearchService elasticsearchService,
        IOptions<ElasticsearchOptions> esOptions,
        ILogger<ElasticsearchController> logger) : base(logger)
    {
        _elasticsearchService = elasticsearchService;
        _esOptions = esOptions.Value;
    }

    /// <summary>
    /// 测试连接
    /// </summary>
    /// <returns></returns>
    [HttpGet("ping")]
    public async Task<IActionResult> Ping()
    {
        try
        {
            var isConnected = await _elasticsearchService.PingAsync();
            
            if (isConnected)
            {
                var result = new
                {
                    Status = "Connected",
                    Uri = _esOptions.Uri,
                    Timestamp = DateTime.UtcNow
                };
                return Success(result, "Elasticsearch连接成功");
            }
            
            return Fail("无法连接到Elasticsearch", 503);
        }
        catch (Exception ex)
        {
            return HandleException(ex, "测试Elasticsearch连接");
        }
    }

    /// <summary>
    /// 获取集群健康状态
    /// </summary>
    /// <returns></returns>
    [HttpGet("health")]
    public async Task<IActionResult> GetClusterHealth()
    {
        try
        {
            var health = await _elasticsearchService.GetClusterHealthAsync();
            
            if (health != null)
            {
                return Success(health, "获取集群健康状态成功");
            }
            
            return Fail("无法获取集群健康状态", 503);
        }
        catch (Exception ex)
        {
            return HandleException(ex, "获取集群健康状态");
        }
    }

    /// <summary>
    /// 创建索引
    /// </summary>
    /// <param name="request">创建索引请求</param>
    /// <returns></returns>
    [HttpPost("index/create")]
    public async Task<IActionResult> CreateIndex([FromBody] CreateIndexRequest request)
    {
        try
        {
            if (string.IsNullOrEmpty(request.IndexName))
            {
                return BadRequest("索引名称不能为空");
            }

            var indexName = _esOptions.Indexes.GetFullIndexName(request.IndexName, _esOptions.IndexPrefix);
            var exists = await _elasticsearchService.IndexExistsAsync(indexName);
            
            if (exists)
            {
                return BadRequest($"索引 {indexName} 已存在");
            }

            var success = await _elasticsearchService.CreateIndexAsync(indexName);
            
            return success 
                ? Success(new { IndexName = indexName }, "索引创建成功") 
                : Fail("索引创建失败");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "创建索引");
        }
    }

    /// <summary>
    /// 删除索引
    /// </summary>
    /// <param name="indexName">索引名称</param>
    /// <returns></returns>
    [HttpDelete("index/{indexName}")]
    public async Task<IActionResult> DeleteIndex(string indexName)
    {
        try
        {
            var fullIndexName = _esOptions.Indexes.GetFullIndexName(indexName, _esOptions.IndexPrefix);
            var exists = await _elasticsearchService.IndexExistsAsync(fullIndexName);
            
            if (!exists)
            {
                return NotFound($"索引 {fullIndexName} 不存在");
            }

            var success = await _elasticsearchService.DeleteIndexAsync(fullIndexName);
            
            return success 
                ? Success("索引删除成功") 
                : Fail("索引删除失败");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "删除索引");
        }
    }

    /// <summary>
    /// 检查索引是否存在
    /// </summary>
    /// <param name="indexName">索引名称</param>
    /// <returns></returns>
    [HttpGet("index/{indexName}/exists")]
    public async Task<IActionResult> IndexExists(string indexName)
    {
        try
        {
            var fullIndexName = _esOptions.Indexes.GetFullIndexName(indexName, _esOptions.IndexPrefix);
            var exists = await _elasticsearchService.IndexExistsAsync(fullIndexName);
            
            return Success(new { IndexName = fullIndexName, Exists = exists }, "查询成功");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "检查索引是否存在");
        }
    }

    /// <summary>
    /// 索引文档
    /// </summary>
    /// <param name="request">索引文档请求</param>
    /// <returns></returns>
    [HttpPost("document/index")]
    public async Task<IActionResult> IndexDocument([FromBody] IndexDocumentRequest request)
    {
        try
        {
            if (string.IsNullOrEmpty(request.IndexName))
            {
                return BadRequest("索引名称不能为空");
            }

            if (request.Document == null)
            {
                return BadRequest("文档不能为空");
            }

            var indexName = _esOptions.Indexes.GetFullIndexName(request.IndexName, _esOptions.IndexPrefix);
            var result = await _elasticsearchService.IndexDocumentAsync(indexName, request.Document, request.DocumentId);
            
            return result.IsSuccess 
                ? Success(result, "文档索引成功") 
                : Fail(result.ErrorMessage ?? "文档索引失败");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "索引文档");
        }
    }

    /// <summary>
    /// 批量索引文档
    /// </summary>
    /// <param name="request">批量索引请求</param>
    /// <returns></returns>
    [HttpPost("document/bulk-index")]
    public async Task<IActionResult> BulkIndexDocuments([FromBody] BulkIndexRequest request)
    {
        try
        {
            if (string.IsNullOrEmpty(request.IndexName))
            {
                return BadRequest("索引名称不能为空");
            }

            if (request.Documents == null || !request.Documents.Any())
            {
                return BadRequest("文档列表不能为空");
            }

            var indexName = _esOptions.Indexes.GetFullIndexName(request.IndexName, _esOptions.IndexPrefix);
            var results = await _elasticsearchService.BulkIndexDocumentsAsync(indexName, request.Documents);
            
            var successCount = results.Count(r => r.IsSuccess);
            var failCount = results.Count - successCount;
            
            return Success(new 
            { 
                Results = results, 
                SuccessCount = successCount,
                FailCount = failCount
            }, $"批量索引完成，成功: {successCount}，失败: {failCount}");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "批量索引文档");
        }
    }

    /// <summary>
    /// 获取文档
    /// </summary>
    /// <param name="indexName">索引名称</param>
    /// <param name="documentId">文档ID</param>
    /// <returns></returns>
    [HttpGet("document/{indexName}/{documentId}")]
    public async Task<IActionResult> GetDocument(string indexName, string documentId)
    {
        try
        {
            var fullIndexName = _esOptions.Indexes.GetFullIndexName(indexName, _esOptions.IndexPrefix);
            var document = await _elasticsearchService.GetDocumentAsync<object>(fullIndexName, documentId);
            
            if (document != null)
            {
                return Success(document, "获取文档成功");
            }
            
            return NotFound("文档不存在");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "获取文档");
        }
    }

    /// <summary>
    /// 删除文档
    /// </summary>
    /// <param name="indexName">索引名称</param>
    /// <param name="documentId">文档ID</param>
    /// <returns></returns>
    [HttpDelete("document/{indexName}/{documentId}")]
    public async Task<IActionResult> DeleteDocument(string indexName, string documentId)
    {
        try
        {
            var fullIndexName = _esOptions.Indexes.GetFullIndexName(indexName, _esOptions.IndexPrefix);
            var success = await _elasticsearchService.DeleteDocumentAsync(fullIndexName, documentId);
            
            return success 
                ? Success("文档删除成功") 
                : Fail("文档删除失败");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "删除文档");
        }
    }

    /// <summary>
    /// 搜索文档
    /// </summary>
    /// <param name="indexName">索引名称</param>
    /// <param name="request">搜索请求</param>
    /// <returns></returns>
    [HttpPost("search/{indexName}")]
    public async Task<IActionResult> Search(string indexName, [FromBody] SearchRequest request)
    {
        try
        {
            var fullIndexName = _esOptions.Indexes.GetFullIndexName(indexName, _esOptions.IndexPrefix);
            var results = await _elasticsearchService.SearchAsync<object>(fullIndexName, request);
            
            return Success(results, "搜索完成");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "搜索文档");
        }
    }

    /// <summary>
    /// 搜索日志
    /// </summary>
    /// <param name="request">搜索请求</param>
    /// <returns></returns>
    [HttpPost("search/logs")]
    public async Task<IActionResult> SearchLogs([FromBody] SearchRequest request)
    {
        try
        {
            var indexName = _esOptions.Indexes.GetFullIndexName(_esOptions.Indexes.Logs, _esOptions.IndexPrefix);
            var results = await _elasticsearchService.SearchAsync<LogDocument>(indexName, request);
            
            return Success(results, "搜索日志完成");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "搜索日志");
        }
    }

    /// <summary>
    /// 搜索用户活动
    /// </summary>
    /// <param name="request">搜索请求</param>
    /// <returns></returns>
    [HttpPost("search/user-activities")]
    public async Task<IActionResult> SearchUserActivities([FromBody] SearchRequest request)
    {
        try
        {
            var indexName = _esOptions.Indexes.GetFullIndexName(_esOptions.Indexes.UserActivities, _esOptions.IndexPrefix);
            var results = await _elasticsearchService.SearchAsync<UserActivityDocument>(indexName, request);
            
            return Success(results, "搜索用户活动完成");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "搜索用户活动");
        }
    }

    /// <summary>
    /// 获取配置的索引
    /// </summary>
    /// <returns></returns>
    [HttpGet("indexes")]
    public IActionResult GetIndexes()
    {
        try
        {
            var indexes = new
            {
                Prefix = _esOptions.IndexPrefix,
                Logs = _esOptions.Indexes.GetFullIndexName(_esOptions.Indexes.Logs, _esOptions.IndexPrefix),
                UserActivities = _esOptions.Indexes.GetFullIndexName(_esOptions.Indexes.UserActivities, _esOptions.IndexPrefix),
                SystemEvents = _esOptions.Indexes.GetFullIndexName(_esOptions.Indexes.SystemEvents, _esOptions.IndexPrefix),
                AuditLogs = _esOptions.Indexes.GetFullIndexName(_esOptions.Indexes.AuditLogs, _esOptions.IndexPrefix)
            };
            
            return Success(indexes, "获取索引配置成功");
        }
        catch (Exception ex)
        {
            return HandleException(ex, "获取索引配置");
        }
    }
}

/// <summary>
/// 创建索引请求
/// </summary>
public class CreateIndexRequest
{
    /// <summary>
    /// 索引名称
    /// </summary>
    public string IndexName { get; set; } = string.Empty;
}

/// <summary>
/// 索引文档请求
/// </summary>
public class IndexDocumentRequest
{
    /// <summary>
    /// 索引名称
    /// </summary>
    public string IndexName { get; set; } = string.Empty;
    
    /// <summary>
    /// 文档ID（可选）
    /// </summary>
    public string? DocumentId { get; set; }
    
    /// <summary>
    /// 文档内容
    /// </summary>
    public object? Document { get; set; }
}

/// <summary>
/// 批量索引请求
/// </summary>
public class BulkIndexRequest
{
    /// <summary>
    /// 索引名称
    /// </summary>
    public string IndexName { get; set; } = string.Empty;
    
    /// <summary>
    /// 文档列表
    /// </summary>
    public List<object> Documents { get; set; } = new();
}

